// Copyright (C) Microsoft Corporation. All rights reserved.

using System;
using System.Text;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Web.Services.Protocols;
using Microsoft.DDSolutions.SharePoint;
using Microsoft.DDSolutions.SqlReportServer;
using Microsoft.DDSolutions.Tfs;
using System.Security.Permissions;

using NUnit.Framework;
using Microsoft.TeamFoundation.Client;

[assembly: CLSCompliant(true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum)]

namespace Microsoft.DDSolutions.TfsAdmin.Tests
{
    /// <summary>
    /// Summary description for ReportServerUnitTests
    /// </summary>
    [TestFixture]
    public class ReportServerUnitTests : IDisposable
    {
        ReportingServiceProxy rsProxy;
        bool disposed;
        TestConfig tc;

        [TestFixtureSetUp]
        public void Init()
        {
            tc = TestConfig.Load("TestConfig.xml");
            TeamFoundationServer tfsAppServer = new TeamFoundationServer(tc.Server);
            Microsoft.DDSolutions.Tfs.TfsServerProxy tfs = new Microsoft.DDSolutions.Tfs.TfsServerProxy();
            tfs.Connect(tfsAppServer);
            rsProxy = new ReportingServiceProxy(tfs.ReportServiceUrl);

            /// Make sure all the Reporting Services Roles assigned for users in the config file actually
            /// exist on the reporting services
            foreach (DomainUser user in tc.DomainUsers)
            {
                /// Make sure the user has atleast one Reporting Services Role assigned.
                Assert.IsTrue(user.RSRoles.Length > 0, TestResource.strMissingRole);

                foreach (string rsRole in user.RSRoles)
                    Assert.IsTrue(rsProxy.IsRoleExist(rsRole));
            }

            /// Add users
            AddUsers();
        }

        [TestFixtureTearDown]
        public void TeardownFixture()
        {
            RemoveUsers();
        }


        /// <summary>
        ///  Add the users specified in the TestConfig file to Reporting services with respective roles.
        /// </summary>
        public void AddUsers()
        {
            foreach (DomainUser user in tc.DomainUsers)
            {
                foreach (string rsRole in user.RSRoles)
                {
                    rsProxy.AddUser(tc.GetDomainUserName(user.UserName), tc.TeamProject, rsRole);
                }
            }
        }

        /// <summary>
        ///  Remove the users specified in the TestConfig file to Reporting services with respective roles.
        /// </summary>
        public void RemoveUsers()
        {
            foreach (DomainUser user in tc.DomainUsers)
            {
                foreach (string rsRole in user.RSRoles)
                {
                    rsProxy.RemoveUser(tc.GetDomainUserName(user.UserName), tc.TeamProject);
                }
            }
        }
        
        /// <summary>
        ///  Dispose method to dispose the Web Service resource.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposed == true) return;

            if (disposing)
            {
                rsProxy.Dispose();
                disposed = true;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        /// <summary>
        ///   Test GetRoles api to verify that the Domain user roles do exist on the server.
        /// </summary>
        [Test]
        public void ReportingServiceGetRoles()
        {
            ReadOnlyCollection<string> actual = rsProxy.Roles;

            foreach (DomainUser user in tc.DomainUsers)
            {
                foreach (string rsRole in user.RSRoles)
                    Assert.Contains(rsRole, actual, rsRole + TestResource.MissingRoleMsg);
            }
        }

        /// <summary>
        ///   Test GetUserRoles api by verifying if the users added during TestFixtureSetup have 
        /// the same roles associated with them.
        /// </summary>
        [Test]
        public void ReportingServiceGetUserRoles()
        {
            ReadOnlyCollection<string> roles;

            foreach (DomainUser user in tc.DomainUsers)
            {
                roles = rsProxy.GetUserRoles(tc.GetDomainUserName(user.UserName), tc.TeamProject);

                foreach (string rsRole in user.RSRoles)
                {
                    Assert.Contains(rsRole, roles, rsRole + TestResource.strMissingRole);
                }
            }
        }

    }
}
